package ar.edu.itba.cg;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;

import ar.edu.itba.cg.controllers.ShootBar;
import ar.edu.itba.cg.menu.BowlingMenu;
import ar.edu.itba.cg.model.Scene;
import ar.edu.itba.cg.score.Player;

import com.jme.input.KeyBindingManager;
import com.jme.input.KeyInput;
import com.jme.math.Vector3f;
import com.jmex.physics.util.SimplePhysicsGame;


public class Bowling extends SimplePhysicsGame{

	private final static int START_SHOOT=0, SELECT_ANGLE=1, SELECT_POWER=2, SELECT_HIGHT=3, SHOOTING=4, SHOOTING_CAM=5, SHOOT_END=6, MENU=7, MENU_PAUSE=8, GAME_OVER=100; ;
	private int game_state, last_state;
	private Scene scene;
	private ShootBar angleBar, powerBar, hightBar;
	private Player currentPlayer;
	private Queue<Player> playerQueue;
	private List<Player> playerPosition;
	private int shoot=1;
	
	private BowlingMenu menu;
	
	public static void main(String[] args) {
		Bowling b= new Bowling();
		b.start();

	}

	@Override
	protected void simpleInitGame() {
		scene= new Scene(display,cam,rootNode,lightState, getPhysicsSpace());
/*
		angleBar= new ShootBar("Angle Bar", new Vector3f(-15,0,0), new Vector3f(15,0,0), -40000, 40000, display);
		powerBar= new ShootBar("Power Bar", new Vector3f(0,-10,0), new Vector3f(0,10,0), 20000, 65000, display);
		hightBar= new ShootBar("Hight Bar", new Vector3f(0,-10,0), new Vector3f(0,10,0), 0, 20000, display);
*/
		angleBar= new ShootBar("Angle Bar", new Vector3f(-15,0,0), new Vector3f(15,0,0), -120000*300f, 120000*300f, display);
		powerBar= new ShootBar("Power Bar", new Vector3f(0,-10,0), new Vector3f(0,10,0), 30000*500, 200000*300, display);
		hightBar= new ShootBar("Hight Bar", new Vector3f(0,-10,0), new Vector3f(0,10,0), 500, 15000*400, display);
		
		angleBar.getLocalTranslation().setZ(250);
		angleBar.getLocalTranslation().setY(-50);
		powerBar.getLocalTranslation().setZ(250);
		powerBar.getLocalTranslation().setX(25);
		powerBar.getLocalTranslation().setY(-20);
		
		hightBar.getLocalTranslation().setZ(250);
		hightBar.getLocalTranslation().setX(-25);
		hightBar.getLocalTranslation().setY(-20);
		
		rootNode.attachChild(angleBar);
		rootNode.attachChild(powerBar);
		rootNode.attachChild(hightBar);
		
		chageDefaultSetup();
		KeyBindingManager.getKeyBindingManager().set("QUIT", KeyInput.KEY_ESCAPE);
		KeyBindingManager.getKeyBindingManager().set("SHOOT", KeyInput.KEY_SPACE);
		KeyBindingManager.getKeyBindingManager().set("RESET", KeyInput.KEY_1);		 
		
		game_state= MENU;
		menu= new BowlingMenu();
		menu.setActive(true);
		
	}
	@Override
	protected void render(float interpolation) {
		super.render(interpolation);
		if(!menu.isFinish()){			
			menu.draw();
		}
	}
	
	@Override
	 protected void simpleUpdate() {
		//scene.simpleUpdate();
		
		if(game_state!=MENU && game_state!=MENU_PAUSE && game_state!=GAME_OVER){
			if(game_state!=SHOOTING_CAM )
			{
				currentPlayer.getBoardScore().show();
			}
			if(game_state==SHOOTING || game_state== SHOOTING_CAM ){
				if(KeyBindingManager.getKeyBindingManager().isValidCommand("RESET", false)){
					game_state= SHOOT_END;
				}
			}
			if(KeyBindingManager.getKeyBindingManager().isValidCommand("QUIT", false)){
				
				if(game_state==MENU_PAUSE){
					game_state= last_state;
					menu.setActive(false);
				}else{				
					menu.setActive(true);
					menu.buildPauseMenu();
					last_state=game_state;
					game_state= MENU_PAUSE;
				}
			}
		}
		
		
		switch (game_state) {
			case START_SHOOT:
				scene.cameraAfterShoot();
				game_state=SELECT_ANGLE;
				break;
			case SELECT_ANGLE:
				if(KeyBindingManager.getKeyBindingManager().isValidCommand("SHOOT", false))   {
					angleBar.stopMove();
					game_state=SELECT_POWER;
				}
				break;
	
			case SELECT_POWER:
				if(KeyBindingManager.getKeyBindingManager().isValidCommand("SHOOT", false))   {
					powerBar.stopMove();
					game_state=SELECT_HIGHT;
				}
				break;
			
			case SELECT_HIGHT:
				if(KeyBindingManager.getKeyBindingManager().isValidCommand("SHOOT", false))   {
					hightBar.stopMove();
					scene.shotBall(angleBar.getValue(), hightBar.getValue(), powerBar.getValue());
					//scene.shotBall(40000*0, 0, 15000); //x max: 40000 - z min:20000 - z max:65000
					game_state=SHOOTING;
				}
				
				break;
				
			case SHOOTING:
				
				if(scene.ballPassMiddle()){
					scene.cameraBeforeShoot();
					game_state= SHOOTING_CAM;
				}else if(scene.isBallOut() || scene.isBallStoped(timer)){
					game_state= SHOOT_END;
				}
				
				break;
			
			case SHOOTING_CAM:
				if(scene.isBallOut() || scene.isBallStoped(timer)){
					game_state= SHOOT_END;
				}
			
				break;
			case SHOOT_END:
				int pins= scene.getFallenPins();
				
				if(shoot==1){
					currentPlayer.setFirstShoot(pins);
				}else if(shoot==2){
					currentPlayer.setSecondShoot(pins);
				}
				
				if((pins==10 || shoot==2) && currentPlayer.getShootCounter()<11){
					if(shoot==2 && currentPlayer.getShootCounter()==10){
						currentPlayer.setFirstShoot(-1);
						currentPlayer.setSecondShoot(-1);
						playerPosition.add(currentPlayer);
						if(!playerQueue.isEmpty()){							
							currentPlayer= playerQueue.remove();
							shoot=1;
						}else{
							currentPlayer=null;
						}
					}else{						
						playerQueue.add(currentPlayer);
						currentPlayer= playerQueue.remove();
					}
					shoot=1;
					scene.attachAllPins();
				}else if (currentPlayer.getShootCounter()==11){
					if(shoot==1){						
						shoot=2;
					}else{
						playerPosition.add(currentPlayer);
						if(!playerQueue.isEmpty()){							
							currentPlayer= playerQueue.remove();
							shoot=1;
						}else{
							currentPlayer=null;
						}
					}
					scene.attachAllPins();
				}else{
					shoot=2;
				}
				
				if(currentPlayer==null || !currentPlayer.continueShooting()){
					int i=0;
					Collections.sort(playerPosition);
					for(Player p: playerPosition){
						p.getBoardScore().changePosition(i++);
					}
					game_state= GAME_OVER;
					
				}else{					
					resetPlay();		
				}
				break;
				
			case MENU:
				menu();
				break;
			case MENU_PAUSE:
				if(menu.isFinish()){
					if(menu.isChange()){
						menu();
					}else{
						game_state=last_state;						
					}
				}
				break;
				
			case GAME_OVER:
				if(KeyBindingManager.getKeyBindingManager().isValidCommand("QUIT", false)){
					game_state=MENU;
					menu.setActive(true);
				}
				
				for(Player p: playerPosition){
					p.getBoardScore().show();
				}
				break;
			
		}
		
		
		
		
	}
	
	private void resetPlay() {
		scene.resetPlay();
		angleBar.startMove();
		powerBar.startMove();
		hightBar.startMove();
		game_state=START_SHOOT;			
	}

	private void menu() {
		if(menu.isFinish()){
			playerQueue= new LinkedList<Player>();
			playerPosition= new ArrayList<Player>();
			for(int i=1; i<= menu.getPlayers(); i++){
				Player p=new Player(i, display);
				playerQueue.add(p);
				/* TEST */
				/*
				for(int j=0; j<10;j++){
					p.setFirstShoot(10);
				}
				*/
			}
			scene.attachAllPins();
			resetPlay();
			shoot=1;
			currentPlayer= playerQueue.remove();
		}
	}

	private void chageDefaultSetup(){
		KeyBindingManager.getKeyBindingManager().remove("exit");
		KeyBindingManager.getKeyBindingManager().remove("camera_out");
		KeyBindingManager.getKeyBindingManager().remove("toggle_depth");
		
		// Make camera still
		input.removeFromAttachedHandlers(cameraInputHandler);
	}

}
